﻿using Newtonsoft.Json;
using System;
using System.Web;
using System.Web.Security;

namespace lwzlz.Application.System
{

    /// <summary>
    /// 用户身份验证
    /// </summary>
    public static class UserAuthentication
    {
        /// <summary>
        /// 写入用户身份验证票证
        /// </summary>
        /// <param name="userName">用户名</param>
        /// <param name="userData">用户数据</param>
        /// <param name="minutes">过期时间(分钟)</param>
        public static void SignIn(string userName, object userData, int minutes)
        {
            // 序列化用户数据
            var data = JsonConvert.SerializeObject(userData);

            if (!(minutes > 0))
            {
                minutes = 1;
            }

            // 实例化一个FormsAuthenticationTicket，它包含登录名以及额外的用户数据
            var ticket = new FormsAuthenticationTicket(
                version: 1,      // 票证版本号
                name: userName,  // 与票证关联的用户名
                issueDate: DateTime.Now, // 票证发出时的本地日期和时间
                expiration: DateTime.Now.AddMinutes(minutes), // 票证过期时的本地日期和时间
                isPersistent: true, // 票据是否存储在持久性Cookie中
                                    // 若为false，设定时间到后票据过期
                                    // 若为true，票据持久有效，设定时间无效
                                    // 当设定为true时只是票据持久，cookie并非持久，需要设定cookie的Expires
                userData: data   // 存储在票证中的用户特定数据
                );
            // 加密Ticket，变成一个加密的字符串。
            var cookieValue = FormsAuthentication.Encrypt(ticket);

            // 根据加密结果实例化登录Cookie
            var cookie = new HttpCookie(FormsAuthentication.FormsCookieName, cookieValue)
            {
                HttpOnly = true,
                Secure = FormsAuthentication.RequireSSL,
                Domain = FormsAuthentication.CookieDomain,
                Path = FormsAuthentication.FormsCookiePath,
                Expires = DateTime.Now.AddMinutes(minutes)
            };

            // 获取当前Http请求上下文
            var context = HttpContext.Current;
            if (context == null)
            {
                throw new InvalidOperationException();
            }

            // 写入Cookie
            context.Response.Cookies.Remove(cookie.Name);
            context.Response.Cookies.Add(cookie);
        }

        /// <summary>
        /// 删除身份验证票证
        /// </summary>
        public static void SingOut()
        {
            FormsAuthentication.SignOut();
        }

        /// <summary>
        /// 获取当前登录用户
        /// </summary>
        /// <returns></returns>
        public static LoginUser GetCurrentUser()
        {
            return GetCurrentUser<LoginUser>();
        }

        /// <summary>
        /// 获取当前登录用户
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        public static T GetCurrentUser<T>() where T : class, new()
        {
            T userData = null;
            try
            {
                // 获取当前Http请求上下文
                var context = HttpContext.Current;
                // 读登录Cookie
                var cookie = context.Request.Cookies[FormsAuthentication.FormsCookieName];
                if (cookie == null || string.IsNullOrEmpty(cookie.Value))
                {
                    // TODO: throw custom exeption
                    return null;
                }
                // 解密Cookie值，获取FormsAuthenticationTicket对象
                var ticket = FormsAuthentication.Decrypt(cookie.Value);
                if (ticket != null && !string.IsNullOrEmpty(ticket.UserData))
                {
                    userData = JsonConvert.DeserializeObject<T>(ticket.UserData);
                }
            }
            catch
            {
                //throw;
                // XXX: 待完善。跳转至登录错误页。
                return null;
            }

            return userData;
        }

        /// <summary>
        /// 验证用户是否已登录
        /// </summary>
        /// <returns></returns>
        public static bool IsLogined()
        {
            return !string.IsNullOrEmpty(GetCurrentUser()?.UserName);
        }


    }
}
